package test;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import dsa.*;

public class JonathanDiDonatoTest {
	LinkedList list;

	@Before
	public void setUp() throws Exception {
		list = new LinkedList();
		list.addLast(3);
		list.addLast(4);
		list.addLast(5);
		list.addFirst(5);
		list.addFirst(1);
		list.addLast(6);
	}

	@After
	public void tearDown() throws Exception {
	}

	/**
	 * tests size, remove index 0, get, getFirst, getLast, removeFirst, removeLast
	 */
	@Test
	public void testOne() {
		assertTrue(list.size() == 6);

		assertTrue(list.removeFirst().equals(1));

		assertTrue(list.getFirst().equals(5));
		assertTrue(list.get(1).equals(3));
		assertTrue(list.get(2).equals(4));
		assertTrue(list.get(3).equals(5));
		assertTrue(list.getLast().equals(6));

		assertTrue(list.removeFirst().equals(5));

		assertTrue(list.getFirst().equals(3));
		assertTrue(list.get(1).equals(4));
		assertTrue(list.get(2).equals(5));
		assertTrue(list.getLast().equals(6));

		assertTrue(list.size() == 4);
	}

	/**
	 * tests remove index 1
	 */
	@Test
	public void testTwo() {
		assertTrue(list.remove(1).equals(5));

		assertTrue(list.getFirst().equals(1));
		assertTrue(list.get(1).equals(3));
		assertTrue(list.get(2).equals(4));
		assertTrue(list.get(3).equals(5));
		assertTrue(list.getLast().equals(6));

		assertTrue(list.remove(1).equals(3));

		assertTrue(list.getFirst().equals(1));
		assertTrue(list.get(1).equals(4));
		assertTrue(list.get(2).equals(5));
		assertTrue(list.getLast().equals(6));
	}

	/**
	 * tests remove index 2
	 */
	@Test
	public void testThree() {
		assertTrue(list.remove(2).equals(3));

		assertTrue(list.getFirst().equals(1));
		assertTrue(list.get(1).equals(5));
		assertTrue(list.get(2).equals(4));
		assertTrue(list.get(3).equals(5));
		assertTrue(list.getLast().equals(6));

		assertTrue(list.remove(2).equals(4));

		assertTrue(list.getFirst().equals(1));
		assertTrue(list.get(1).equals(5));
		assertTrue(list.get(2).equals(5));
		assertTrue(list.getLast().equals(6));
	}

	/**
	 * tests remove index 3
	 */
	@Test
	public void testFour() {
		assertTrue(list.remove(3).equals(4));

		assertTrue(list.getFirst().equals(1));
		assertTrue(list.get(1).equals(5));
		assertTrue(list.get(2).equals(3));
		assertTrue(list.get(3).equals(5));
		assertTrue(list.getLast().equals(6));

		assertTrue(list.remove(3).equals(5));

		assertTrue(list.getFirst().equals(1));
		assertTrue(list.get(1).equals(5));
		assertTrue(list.get(2).equals(3));
		assertTrue(list.getLast().equals(6));
	}

	/**
	 * tests remove index 4
	 */
	@Test
	public void testFive() {
		assertTrue(list.remove(4).equals(5));

		assertTrue(list.getFirst().equals(1));
		assertTrue(list.get(1).equals(5));
		assertTrue(list.get(2).equals(3));
		assertTrue(list.get(3).equals(4));
		assertTrue(list.getLast().equals(6));

		assertTrue(list.remove(4).equals(6));

		assertTrue(list.getFirst().equals(1));
		assertTrue(list.get(1).equals(5));
		assertTrue(list.get(2).equals(3));
		assertTrue(list.getLast().equals(4));
	}

	/**
	 * tests remove index 5
	 */
	@Test
	public void testSix() {
		assertTrue(list.removeLast().equals(6));

		assertTrue(list.getFirst().equals(1));
		assertTrue(list.get(1).equals(5));
		assertTrue(list.get(2).equals(3));
		assertTrue(list.get(3).equals(4));
		assertTrue(list.getLast().equals(5));

		assertTrue(list.removeLast().equals(5));

		assertTrue(list.getFirst().equals(1));
		assertTrue(list.get(1).equals(5));
		assertTrue(list.get(2).equals(3));
		assertTrue(list.getLast().equals(4));
	}

	/**
	 * tests indexOf, contains, set
	 */
	@Test
	public void testSeven() {
		assertTrue(list.indexOf(1) == 0);
		assertTrue(list.indexOf(5) == 1);
		assertTrue(list.indexOf(3) == 2);
		assertTrue(list.indexOf(4) == 3);
		assertTrue(list.indexOf(6) == 5);
		assertTrue(list.indexOf(23) == -1);

		assertTrue(list.contains(1) == true);
		assertTrue(list.contains(5) == true);
		assertTrue(list.contains(3) == true);
		assertTrue(list.contains(6) == true);
		assertTrue(list.contains(7) == false);

		assertTrue(list.set(0,12).equals(1));
		assertTrue(list.get(0).equals(12));

		assertTrue(list.set(1,6).equals(5));
		assertTrue(list.get(1).equals(6));

		assertTrue(list.set(2,8).equals(3));
		assertTrue(list.get(2).equals(8));

		assertTrue(list.set(3,0).equals(4));
		assertTrue(list.get(3).equals(0));

		assertTrue(list.set(4,9).equals(5));
		assertTrue(list.get(4).equals(9));

		assertTrue(list.set(5,19).equals(6));
		assertTrue(list.get(5).equals(19));
	}

	/**
	 * tests clone, toArray
	 */
	@Test
	public void testEight() {
		LinkedList list2 = (LinkedList) list.clone();
		for(int i = 0;i < list.size();i++)
			assertTrue(list.get(i).equals(list2.get(i)));

		Object array[] = new Object[list.size()];
		array = list.toArray();
		for(int i = 0;i < array.length;i++)
			assertTrue(list.get(i).equals(array[i]));
	}

	/**
	 * tests ListIterator
	 */
	@Test
	public void testNine() {
		ListIterator itr = list.listIterator(1);
		int count = 2;
		itr.next();
		itr.set(2);
		
		while(itr.hasNext())
			itr.next(); 
		
		itr.add(7);
		itr.add(8);
		
		while(itr.hasPrevious())
			itr.previous();
		
		itr.remove();
		
		assertTrue(itr.nextIndex() == 0);
		assertTrue(itr.previousIndex() == -1);
		
		while(itr.hasNext()){
			assertTrue(itr.next().equals(count));
			count++;
		} 
		
		assertTrue(itr.nextIndex() == 7);
		assertTrue(itr.previousIndex() == 6);
		
		while(itr.hasPrevious())
			itr.previous();
		
		itr.next();
		itr.next();
		itr.remove();
		
		itr.previous();
		
		count = 2;
		while(itr.hasNext()){
			if(count == 3)
				count++;
			assertTrue(itr.next().equals(count));
			count++;
		} 
	}
}